-- Clientside overrides
local ENT = FindMetaTable("Entity")

local oldEmitSound = ENT.EmitSound
function ENT:EmitSound( filename, soundlevel, pitchpercent )
	if LocalPlayer():GetCell() != self:GetCell() then return end
	
	oldEmitSound( self, filename, soundlevel, pitchpercent )
end

local oldCreateParticleEffect = ENT.CreateParticleEffect
function ENT:CreateParticleEffect( name, points )
	if LocalPlayer():GetCell() != self:GetCell() then return end
	
	oldCreateParticleEffect( self, name, points )
end

local SPatch = FindMetaTable("CSoundPatch")

local oldCreateSound = CreateSound
function CreateSound( target, path )
	local soundPatch = CreateSound( target, path )
	soundPatch.Target = target
	return soundPatch
end

local oldPlay = SPatch.Play
function SPatch:Play( )
	if LocalPlayer():GetCell() != self.Target:GetCell() then return end
	
	oldPlay( self )
end

local oldPlayEx = SPatch.PlayEx

function SPatch:PlayEx( volume, pitch )
	if LocalPlayer():GetCell() != self.Target:GetCell() then return end
	
	oldPlayEx( self, volume, pitch )
end

-- View override... edited version of garry's code, not great
function cells.CalcViewForVehicles( Vehicle, ply, origin, angles, fov )

    local view = {}
    view.angles        = angles
    view.fov         = fov
    
    if ( !Vehicle.CalcView ) then
    
        Vehicle.CalcView = {}
        
        // Try to work out the size
        local min, max = Vehicle:WorldSpaceAABB()
        local size = max - min
        
        Vehicle.CalcView.OffsetUp = size.z
        Vehicle.CalcView.OffsetOut = (size.x + size.y + size.z) * 0.33
    
    end
    
    -- Offset the origin
    local Up = view.angles:Up() * Vehicle.CalcView.OffsetUp * 0.66
    local Offset = view.angles:Forward() * -Vehicle.CalcView.OffsetOut
    
    -- Trace back from the original eye position, so we don't clip through walls/objects
    local TargetOrigin = Vehicle:GetPos_cell() + Up + Offset
	_cell, origin = cells.AbsoluteToLocal( origin ) -- FIX THIRD PERSON VIEW.
    local distance = origin - TargetOrigin
    
    local trace = {
                    start = origin,
                    endpos = TargetOrigin,
                    filter = Vehicle
                  }
                  
                  
    local tr = util.TraceLine( trace ) 
    
    view.origin = origin + tr.Normal * (distance:Length() - 10) * tr.Fraction
        
    return view

end

local gmod_vehicle_viewmode = GetConVar( "gmod_vehicle_viewmode" )

function cells.VehicleCalcView( ply, pos, angles, fov )
	local Vehicle = ply:GetVehicle()

	if ( ValidEntity( Vehicle ) and gmod_vehicle_viewmode:GetInt() == 1 and ply:ShouldDrawLocalPlayer() ) then
		return cells.CalcViewForVehicles( Vehicle, ply, pos*1, angles*1, fov )
	end
end

hook.Add( "CalcView", "cells.VehicleCalcView", cells.VehicleCalcView )